package com.coocaa.ops.plus.core.third.visionhub.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.coocaa.ops.common.tool.base.InstanceUtil;
import com.coocaa.ops.plus.core.third.visionhub.model.PosterSimilarityInfo;
import com.coocaa.ops.plus.core.third.visionhub.model.PosterSimilarityResultModel;
import lombok.experimental.UtilityClass;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author bjh
 * @description
 * @date 2021/5/14 18:46
 */
@UtilityClass
public class PosterSimilarityHandler {

    public static List<PosterSimilarityResultModel> parseResult(String result, MultipartFile[] files) {
        BASE64Encoder encoder = new BASE64Encoder();
        List<PosterSimilarityResultModel> similarityModelList = InstanceUtil.newArrayList();
        JSONArray data = JSON.parseObject(result).getJSONArray("data");
        int size = data.size();
        int index = 0;
        Map<String, String> fileNameBase64Map = InstanceUtil.newHashMap();
        for (; index < size; index++) {
            JSONObject item = data.getJSONObject(index);
            PosterSimilarityResultModel similarityModel = getPosterSimilarityModel(item, files, encoder, fileNameBase64Map);
            similarityModelList.add(similarityModel);
        }
        return similarityModelList;
    }



    public static MultipartFile findMultipartFile(String fileName, MultipartFile[] file) {
        for (MultipartFile multipartFile : file) {
            String name = multipartFile.getOriginalFilename();
            if (Objects.equals(name, fileName)) {
                return multipartFile;
            }
        }
        return null;
    }

    public static String getBase64(MultipartFile file, BASE64Encoder encoder) {
        try {
            String fileStr = encoder.encode(file.getBytes());
            String contentType = file.getContentType();
//            fileStr = "data:image/jpg;base64," + fileStr;
            fileStr = "data:" + contentType + ";base64," + fileStr;
            return fileStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private static PosterSimilarityResultModel getPosterSimilarityModel(JSONObject item, MultipartFile[] file, BASE64Encoder encoder, Map<String, String> fileNameBase64Map) {
        List<String> ulrs = getUrls(item);
        List<PosterSimilarityInfo> base64s = getBase64s(ulrs, file, encoder, fileNameBase64Map);
        PosterSimilarityResultModel similarityModel = new PosterSimilarityResultModel();
        similarityModel.setPosters(base64s);
        Float score = item.getFloat("score");
        similarityModel.setScore(score);
        return similarityModel;
    }

    private static List<String> getUrls(JSONObject item) {
        List<String> result = InstanceUtil.newArrayList();
        JSONArray urls = item.getJSONArray("urls");
        int size = urls.size();
        int index = 0;
        for (; index < size; index++) {
            String url = (String) urls.get(index);
            result.add(url);
        }
        return result;
    }


    private static List<PosterSimilarityInfo> getBase64s(List<String> ulrs, MultipartFile[] file, BASE64Encoder encoder, Map<String, String> fileNameBase64Map) {
        List<PosterSimilarityInfo> result = InstanceUtil.newArrayList();
        for (String name : ulrs) {
            String base64 = fileNameBase64Map.get(name);
            if (null == base64) {
                base64 = getBase64(name, file, encoder);
                if (null != base64) {
                    fileNameBase64Map.put(name, base64);
                    PosterSimilarityInfo posterSimilarityInfo = new PosterSimilarityInfo(base64, name);
                    result.add(posterSimilarityInfo);
                }
            }
        }
        return result;
    }

    private static String getBase64(String fileName, MultipartFile[] file, BASE64Encoder encoder) {
        MultipartFile multipartFile = findMultipartFile(fileName, file);
        return getBase64(multipartFile, encoder);
    }


}
